package info

import (
	"encoding/json"
	"fmt"
	"strconv"
	"time"

	"github.com/yusufpapurcu/wmi"
	//"github.com/StackExchange/wmi"
)

// 物理内存
type Win32_PhysicalMemory struct {
	Attributes           uint32 `json:"属性"`
	BankLabel            string `json:"物理标记的库"`
	Capacity             uint64 `json:"容量"`
	Caption              string `json:"简间说明"`
	ConfiguredClockSpeed uint32 `json:"配置时钟速度"`
	ConfiguredVoltage    uint32 `json:"配置电压(毫伏)"`
	CreationClassName    string
	DataWidth            uint16    `json:"数据宽度"`
	Description          string    `json:"描述"`
	DeviceLocator        string    `json:"插槽位置"`
	FormFactor           uint16    `json:"外形规格"`
	HotSwappable         bool      `json:"热交换"`
	InstallDate          time.Time `json:"安装时间"`
	InterleaveDataDepth  uint16    `json:"单个交错传输中访问"`
	InterleavePosition   uint32    `json:"物理内存的位置"`
	Manufacturer         string    `json:"制造厂商"`
	MaxVoltage           uint      `json:"最大工作电压(毫伏)"`
	MemoryType           uint      `json:"物理内存的类型"`
	MinVoltage           uint      `json:"最小工作电压(毫伏)"`
	Model                string    `json:"物理元素名称"`
	Name                 string    `json:"名称"`
	OtherIdentifyingInfo string    `json:"标识物理元素"`
	PartNumber           string    `json:"物理元素部件号"`
	PositionInRow        uint32
	PoweredOn            bool   `json:"打开物理元素"`
	Removable            bool   `json:"是否移动"`
	Replaceable          bool   `json:"是否可更换"`
	SerialNumber         string `json:"序列号"`
	SKU                  string `json:"物理元素库存单位号"`
	SMBIOSMemoryType     uint32 `json:"SMBIOS内存类型"`
	Speed                uint32 `json:"物理内存的速度"`
	Status               string `json:"状态"`
	Tag                  string `json:"标记"`
	TotalWidth           uint16 `json:"物理内存的总宽度"`
	TypeDetail           uint16 `json:"SMBIOS信息中内存设备类型"`
	Version              string `json:"物理元素的版本"`
}
type Win32_PhysicalMemoryArray struct {
	Caption               string `json:"简单说明"`
	CreationClassName     string
	Depth                 float32   `json:"物理内存深度"`
	Description           string    `json:"物理内存描述"`
	Height                float32   `json:"物理内存高度"`
	HotSwappable          bool      `json:"热交换"`
	InstallDate           time.Time `json:"安装时间"`
	Location              uint      `json:"物理内存位置"`
	Manufacturer          string    `json:"组织的名称"`
	MaxCapacity           uint
	MaxCapacityEx         uint    `json:"最大内存大小"`
	MemoryDevices         uint16  `json:"内存物理槽"`
	MemoryErrorCorrection uint    `json:"错误更正的类型"`
	Model                 string  `json:"物理元素的名称"`
	Name                  string  `json:"名称"`
	OtherIdentifyingInfo  string  `json:"标识物理元素"`
	PartNumber            string  `json:"部件号"`
	PoweredOn             bool    `json:"物理元素是否打开"`
	Removable             bool    `json:"是否可移动"`
	Replaceable           bool    `json:"是否可替换"`
	SerialNumber          string  `json:"序列号"`
	SKU                   string  `json:"库存编号"`
	Status                string  `json:"库存单位编号"`
	Tag                   string  `json:"标记"`
	Use                   uint16  `json:"使用"`
	Version               string  `json:"版本"`
	Weight                float32 `json:"重量"`
	Width                 float32 `json:"宽度"`
}

func PhysicalMemoryInfo() (physicalMemoryInfo []Win32_PhysicalMemory, err error) {
	err1 := wmi.Query("Select * from Win32_PhysicalMemory", &physicalMemoryInfo)
	if err1 != nil {
		return nil, err1
	}
	return physicalMemoryInfo, nil
}
func JsonPhysicalMemoryInfo() (f []byte, err error) {
	cpu, err := PhysicalMemoryInfo()
	if err != nil {
		return f, err
	}
	t, jsonerr := json.Marshal(cpu)
	if jsonerr != nil {
		return f, jsonerr
	}
	return t, nil

}

func MapPhysicalMemoryInfo() (data []map[string]interface{}, err error) {
	//data := make([]map[string]interface{}, 0)
	t, err1 := JsonPhysicalMemoryInfo()
	if err1 != nil {
		return data, err1
	}
	json.Unmarshal(t, &data)
	/* cfg, err1 := ini.Load("./info/processorconfig.ini")
	if err1 != nil {
		return data, err
	}
	list := []string{"体系结构", "系列", "主要功能", "CPU套接字信息", "可用性", "特征", "使用情况"}
	for _, v := range data {
		for _, vl := range list {
			if a, ok := v[vl].(float64); ok {
				v[vl] = cfg.Section(cfg.Section("").Key(vl).String()).Key(strconv.Itoa(int(a))).String()
			} else {
				continue
			}

		}
		//fmt.Println(cfg.Section(d.String()).Key(fmt.Sprintf("%v", v1)))
	} */
	for _, vd := range data {

		if v, ok := vd["容量"].(float64); ok {
			if v > 1073741824 {
				vd["容量"] = fmt.Sprintf("%d", (int64(v)/1073741824)) + "GB"
			} else {
				vd["容量"] = strconv.Itoa(int(v)) + "B"
			}

		}

	}
	return data, nil

}

/*
	 func JsonPhysicalMemoryInfo() (f interface{}, err error) {
		info, err := PhysicalMemoryInfo()
		if err != nil {
			return "", err
		}
		f, err = json.Marshal(info)
		if err != nil {
			return "", err
		}
		memory, err := exec.Command("wmic", "memorychip", "get", "Model").Output()
		if err != nil {
			fmt.Println(err)
			return
		}
		memorySize := strings.TrimSpace(string(memory))
		fmt.Println(memorySize)
		return f, nil
	}
*/
func PhysicalMemoryArrayInfo() (f interface{}, err error) {
	var physicalMemoryInfo []Win32_PhysicalMemoryArray
	err1 := wmi.Query("Select * from Win32_PhysicalMemoryArray", &physicalMemoryInfo)
	if err1 != nil {
		return "", err1
	}
	f, err = json.Marshal(physicalMemoryInfo)
	if err != nil {
		return "", err
	}
	return f, nil
}
